
package com.viweb.storemanager.core;


import com.viweb.storemanager.temp.BooleanCellRenderer;
import com.viweb.storemanager.temp.NumberCellRenderer;
import com.viweb.storemanager.temp.RadioButtonCellRenderer;
import com.viweb.storemanager.temp.TextCellRenderer;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

public class DefaultObjectTableModel extends AbstractTableModel {

    private JTable mainTable;
    private JTable headerTable;
    private List tableData;
    private ColumnData[] columns;

    /**
     * Creates a new instance of DefaultObjectTableModel
     * with defaul empty data
     */
    public DefaultObjectTableModel(JTable mainTable, ColumnData[] columns) {
        this.mainTable = mainTable;
        this.tableData = new ArrayList();
        this.columns = columns;

        // Init table UI behaviour
        this.mainTable.setShowGrid(false);
        this.mainTable.setModel(this);
        this.initTableColumns();
    }

    /** Creates a new instance of DefaultObjectTableModel */
    public DefaultObjectTableModel(JTable mainTable, ColumnData[] columns, List tableData) {
        this.mainTable = mainTable;
        if (tableData == null) {
            this.tableData = new ArrayList();
        } else {
            this.tableData = tableData;
        }
        this.columns = columns;

        // Init table UI behaviour
        this.mainTable.setShowGrid(false);
        this.mainTable.setModel(this);
        this.initTableColumns();
    }

    /** Creates a new instance of DefaultObjectTableModel */
    public DefaultObjectTableModel(JTable table, ColumnData[] columns, List tableData, boolean autoResize) {
        this.mainTable = table;
        if (tableData == null) {
            this.tableData = new ArrayList();
        } else {
            this.tableData = tableData;
        }
        this.columns = columns;

        // Init table UI behaviour
        this.mainTable.setShowGrid(false);
        if (!autoResize) {
            this.mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        }
        this.mainTable.setModel(this);
        this.initTableColumns();
    }

    @Override
    public String getColumnName(int index) {
        if (index == 0) {
            return "";
        }

        return " " + this.columns[index - 1].getName() + " ";
    }

    public int getColumnCount() {
        return this.columns.length + 1;
    }

    public int getRowCount() {
        return this.tableData.size();
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        // If this is the first comlumn (order comlum)
        if (columnIndex == 0) {
            // Show the order of this row
            int order = rowIndex + 1;

            return "" + order;
        }

        int index = this.getColumnPropertyIndex(columnIndex - 1);
        PropertyIndex propertyIndex = (PropertyIndex) this.tableData.get(rowIndex);
        Object value = propertyIndex.getPropertyValue(index);

        return value;
    }

    public Object getValueAt(int rowIndex) {
        Object value = this.tableData.get(rowIndex);

        return value;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        if (this.getColumnClass(columnIndex) == String.class) {
            super.setValueAt(aValue, rowIndex, columnIndex);
        } else {
            int index = this.getColumnPropertyIndex(columnIndex - 1);
            PropertyIndex propertyIndex = (PropertyIndex) this.tableData.get(rowIndex);
            propertyIndex.setPropertyValue(index, aValue);
            this.fireTableCellUpdated(rowIndex, columnIndex);
        }
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        // If this is the first comlumn (order comlum)
        if (columnIndex == 0) {
            return false;
        }

        return this.columns[columnIndex - 1].isEditable();
    }

    private int getColumnPropertyIndex(int columnIndex) {
        return this.columns[columnIndex].getPropertyIndex();
    }

    private void initTableColumns() {
        if ((this.columns != null) & (this.columns.length > 0)) {
            for (int i = 0; i < this.columns.length; i++) {
                TableColumn column = this.mainTable.getColumnModel().getColumn(i + 1);
                TableCellRenderer cellRenderer = null;

                // If renderer for the comlumn is Default (Text)
                if (this.columns[i].getRenderer() == ColumnData.DEFAULT_RENDERER) {
                    cellRenderer = new TextCellRenderer();
                    ((DefaultTableCellRenderer) cellRenderer).setHorizontalAlignment(this.columns[i].getAlignment());
                    // If renderer for the comlumn Number
                } else if (this.columns[i].getRenderer() == ColumnData.NUMBER_RENDERER) {
                    cellRenderer = new NumberCellRenderer();
                    ((DefaultTableCellRenderer) cellRenderer).setHorizontalAlignment(this.columns[i].getAlignment());
                    // If renderer for the comlumn Boolean
                } else if (this.columns[i].getRenderer() == ColumnData.BOOLEAN_RENDERER) {
                    cellRenderer = new BooleanCellRenderer();
                    // If renderer for the comlumn Button
                } else if (this.columns[i].getRenderer() == ColumnData.BUTTON_RENDERER) {
                    cellRenderer = new ButtonCellRenderer(this.columns[i].getImageIcon());
                    if (this.columns[i].getAction() != null) {
                        TableCellEditor cellEditor = new ButtonCellEditor(this.columns[i].getAction(), this.columns[i].getImageIcon());
                        column.setCellEditor(cellEditor);
                    }
                    // If renderer for the comlumn Radio button
                } else if (this.columns[i].getRenderer() == ColumnData.RADIO_BUTTON_RENDERER) {
                    cellRenderer = new RadioButtonCellRenderer();
                }

                column.setResizable(true);
                column.setPreferredWidth((this.columns[i]).getWidth());
                column.setCellRenderer(cellRenderer);

                HeaderRenderer headerRenderer = new HeaderRenderer(this.columns[i].getAlignment());
                column.setHeaderRenderer(headerRenderer);
            }

            // Delete order column in the main talble
            this.mainTable.removeColumn(mainTable.getColumnModel().getColumn(0));
        }
    }

    public void updateModel(List tableData) {
        if (tableData == null) {
            this.tableData = new ArrayList();
        } else {
            this.tableData = tableData;
        }
        this.mainTable.updateUI();
        this.headerTable.updateUI();
    }

    public JTable getHeaderTable() {
        if (this.headerTable == null) {
            this.headerTable = createHeaderTable();
        }

        return this.headerTable;
    }

    private JTable createHeaderTable() {
        // Create a column model that will serve as our row header table. This
        // model picks a maximum width and only stores the isFirstColumn column.
        TableColumnModel rowHeaderModel = new DefaultTableColumnModel() {

            boolean isFirstColumn = true;

            @Override
            public void addColumn(TableColumn tableColumn) {
                if (isFirstColumn) {
                    HeaderRenderer headerRenderer = new HeaderRenderer(HeaderRenderer.CENTER);
                    tableColumn.setHeaderRenderer(headerRenderer);

                    TextCellRenderer cellRenderer = new TextCellRenderer(true);
                    cellRenderer.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
                    tableColumn.setCellRenderer(cellRenderer);

                    tableColumn.setMaxWidth(30);
                    super.addColumn(tableColumn);
                    isFirstColumn = false;
                }
                // Drop the rest of the columns . . . this is the header column
                // only
            }
        };

        JTable table = new JTable(DefaultObjectTableModel.this, rowHeaderModel);
        this.mainTable.setSelectionModel(table.getSelectionModel());

        table.setFont(this.mainTable.getFont());
        table.setRowHeight(this.mainTable.getRowHeight());
        table.setColumnSelectionAllowed(false);
        table.setCellSelectionEnabled(false);
        table.getTableHeader().setReorderingAllowed(false);
        table.setShowGrid(false);

        return table;
    }
}
